import random
import re
from datetime import datetime
from flask import request, abort, current_app, make_response, jsonify, session
from info import sr, db
from info.models import User
from info.utils.captcha.pic_captcha import captcha
from info.utils.response_code import RET, error_map
from . import passport_blu


@passport_blu.route('/get_img_code')
def get_img_code():
    img_code_id = request.args.get("img_code_id")
    if not img_code_id:
        return abort(403)

    img_name, img_code_text, img_code_bytes = captcha.generate_captcha()
    try:
        sr.set("img_code_id" + img_code_id, img_code_text, ex=180)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)
    response = make_response(img_code_bytes)
    response.content_type = "image/jpeg"
    return response


@passport_blu.route('/get_sms_code', methods=["POST"])
def get_sms_code():
    img_code_id = request.json.get("img_code_id")
    mobile = request.json.get("mobile")
    img_code = request.json.get("img_code")

    if not all([img_code_id, mobile, img_code]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    if not re.match(r"1[35678]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    try:
        real_img_code = sr.get("img_code_id" + img_code_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if not real_img_code:
        return jsonify(errno=RET.PARAMERR, errmsg="验证码已过期")
    if img_code.upper() != real_img_code:
        return jsonify(errno=RET.PARAMERR, errmsg="验证码错误")

    sms_code = "%04d" % random.randint(0, 9999)
    current_app.logger.info("短信验证码为: %s" % sms_code)
    try:
        sr.set("sms_code_id" + mobile, sms_code, ex=60)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


@passport_blu.route('/register', methods=['POST'])
def register():
    mobile = request.json.get("mobile")
    password = request.json.get("password")
    sms_code = request.json.get("sms_code")

    if not all([mobile, password, sms_code]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    if not re.match(r"1[35678]\d{9}$", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    try:
        real_sms_code = sr.get("sms_code_id" + mobile)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if not real_sms_code:
        return jsonify(errno=RET.PARAMERR, errmsg="验证码已过期")
    if sms_code != real_sms_code:
        return jsonify(errno=RET.PARAMERR, errmsg="验证码错误")

    user = User()
    user.mobile = mobile
    user.password = password
    user.nick_name = mobile
    user.last_login = datetime.now()
    try:
        db.session.add(user)
        db.session.commit()
    except BaseException as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    session["user_id"] = user.id

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


@passport_blu.route("/login", methods=["POST"])
def login():
    get_mobile = request.json.get("mobile")
    get_password = request.json.get("password")

    if not all([get_mobile, get_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    if not re.match(r"1[35678]\d{9}$", get_mobile):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    try:
        user = User.query.filter_by(mobile=get_mobile).first()
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if not user:
        return jsonify(errno=RET.USERERR, errmsg=error_map[RET.USERERR])

    if not user.check_password(get_password):
        return jsonify(errno=RET.PWDERR, errmsg=error_map[RET.PWDERR])

    user.last_login = datetime.now()
    session["user_id"] = user.id

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


@passport_blu.route('/logout')
def logout():
    session.pop("user_id", None)
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])
